package game;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import net.jcip.annotations.GuardedBy;

public class Warehouse {

	private final Lock lock = new ReentrantLock();
	private final Condition condition = lock.newCondition();
	private boolean hasLock = false;
	@GuardedBy("lock") private int currentCount;
	@GuardedBy("lock") private Resource resource;
	private int capacity;

	public Warehouse(int capacity, Types type) {
		resource = new Resource(type, 0);
		this.capacity = capacity;
		this.currentCount = 0;
	}

	public Types getType() {
		return resource.getType();
	}

	public void addInput(int quantity) throws InterruptedException {
		try {
			lock.lockInterruptibly();
			hasLock = true;
			try {
				while (currentCount + quantity > capacity) {
					condition.await();
				}
				resource.increase(quantity);
				currentCount += quantity;
				condition.signalAll();
			} catch (InterruptedException e) {
				Thread.currentThread().interrupt();
			}
		} finally {
			if (hasLock) {
				lock.unlock();
				hasLock = false;
			}
		}
	}

	public Resource takeOutput(int quantity) throws InterruptedException {
		try {
			lock.lockInterruptibly();
			try {
				while (currentCount < quantity) {
					condition.await();
				}
				currentCount -= quantity;
				resource.decrease(quantity);
				Resource res = new Resource(resource.getType(), quantity);
				condition.signalAll();
				return res;
			} catch (InterruptedException e) {
				Thread.currentThread().interrupt();
			}
		} finally {
			if (hasLock) {
				lock.unlock();
				hasLock = false;
			}
		}
		return null;
	}

}
